package com.sparrow.gate.config;

import com.sparrow.gate.iohander.MinaClientIoHandler;
import com.sparrow.gate.iohander.MinaServerIoHandler;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.executor.OrderedThreadPoolExecutor;
import org.apache.mina.filter.logging.MdcInjectionFilter;
import org.apache.mina.filter.util.SessionAttributeInitializingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import java.net.InetSocketAddress;

@Configuration
//@ConfigurationProperties(prefix = "mina")
//@ImportResource(locations = {"classpath:applicationContext-mina.xml"})
public class MinaConfig
{

    private final static Logger logger = LoggerFactory.getLogger(MinaConfig.class);

    //@Bean注解注册bean,同时可以指定初始化和销毁方法
    //@Bean(name="testNean",initMethod="start",destroyMethod="cleanUp")
    //@Bean
    //@Scope("prototype")
    //public  TestBean testBean() {
    //    return new TestBean();
    //}

    @Value("${mina.threadpool.maxnum}")
    private int minaThreadpoolMaxnum;

    @Value("${mina.threadpool.minnum}")
    private int minaThreadpoolMinnum;

    @Value("${mina.listenport}")
    private int minaListenport;


    @Bean
    public ExecutorFilter executorFilter()
    {
        logger.info("minaThreadpoolMaxnum : " + minaThreadpoolMaxnum);
        logger.info("minaThreadpoolMinnum : " + minaThreadpoolMinnum);
        OrderedThreadPoolExecutor orderedThreadPoolExecutor = new OrderedThreadPoolExecutor();
        orderedThreadPoolExecutor.setMaximumPoolSize(minaThreadpoolMaxnum);
        orderedThreadPoolExecutor.setCorePoolSize(minaThreadpoolMinnum);
        return new ExecutorFilter(orderedThreadPoolExecutor);
    }

    @Bean
    public MdcInjectionFilter mdcInjectionFilter()
    {
        return new MdcInjectionFilter();
    }

    @Bean
    public SessionAttributeInitializingFilter sessionAttrFilter()
    {
        return new SessionAttributeInitializingFilter();
    }

    //@Autowired
    //public ExecutorFilter executorFilter;

    //@Autowired
    //public MdcInjectionFilter mdcInjectionFilter;

    //@Autowired
    //public SessionAttributeInitializingFilter sessionAttrFilter;

    @Bean
    public DefaultIoFilterChainBuilder filterChainBuilder(ExecutorFilter executorFilter, MdcInjectionFilter mdcInjectionFilter, SessionAttributeInitializingFilter sessionAttrFilter)
    {
        DefaultIoFilterChainBuilder filterChainBuilder = new DefaultIoFilterChainBuilder();
        filterChainBuilder.addLast("executor", executorFilter);
        filterChainBuilder.addLast("mdc", mdcInjectionFilter);
        filterChainBuilder.addLast("sessionAttr", sessionAttrFilter);
        return filterChainBuilder;
    }

    @Bean
    public InetSocketAddress inetSocketAddress()
    {
        return new InetSocketAddress(minaListenport);
    }

    @Bean
    public IoAcceptor ioAcceptor(DefaultIoFilterChainBuilder ioFilterChainBuilder, MinaServerIoHandler serverIoHandler) throws Exception
    {
        IoAcceptor acceptor = new NioSocketAcceptor();
        acceptor.setFilterChainBuilder(ioFilterChainBuilder);

        //acceptor.getFilterChain().addLast( "executor", executorFilter );
        //acceptor.getFilterChain().addLast( "mdc", mdcInjectionFilter );
        //acceptor.getFilterChain().addLast( "sessionAttr", sessionAttrFilter );

        //acceptor.getFilterChain().addLast( "logger", loggingFilter() );
        //acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory(Charset.forName("UTF-8"))));因为传byte[]所以去掉

        acceptor.setHandler(serverIoHandler);


        acceptor.getSessionConfig().setReadBufferSize(2048);
        //acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );

        acceptor.bind(inetSocketAddress());
        logger.info("服务器在端口：" + minaListenport + "已经启动");
        return acceptor;
    }

    @Bean
    @Scope("singleton")
    public IoConnector ioConnector(DefaultIoFilterChainBuilder ioFilterChainBuilder, MinaClientIoHandler clientIoHandler) throws Exception
    {
        IoConnector connector = new NioSocketConnector();
        connector.setFilterChainBuilder(ioFilterChainBuilder);
        connector.setHandler(clientIoHandler);
        return connector;
    }

}
